package com.juyu.miliao.api;

import com.juyu.miliao.api.config.SegmentedLockManager;
import com.juyu.miliao.api.util.SpringContextUtil;
import com.juyu.miliao.common.util.oss.OSSConfig;
import org.hibernate.validator.HibernateValidator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.web.http.HeaderHttpSessionIdResolver;
import org.springframework.session.web.http.HttpSessionIdResolver;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@SpringBootApplication
@EnableRedisHttpSession
@EnableCaching
public class SocialApiApplication {

    public static void main(String[] args) {
        ApplicationContext socialApiApplication = SpringApplication.run(SocialApiApplication.class, args);
        SpringContextUtil.setApplicationContext(socialApiApplication);
    }

    @Bean
    public HttpSessionIdResolver httpSessionIdResolver() {
        return HeaderHttpSessionIdResolver.xAuthToken();
    }

    @Bean
    public LocalValidatorFactoryBean failFastvalidator() {
        LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setProviderClass(HibernateValidator.class);
        Map<String, String> validationProperties = new HashMap<>();
        validationProperties.put("hibernate.validator.fail_fast", "true");
        localValidatorFactoryBean.setValidationPropertyMap(validationProperties);
        return localValidatorFactoryBean;
    }

    @Bean
    @ConfigurationProperties("app.oss")
    public OSSConfig ossConfig() {
        return new OSSConfig();
    }


//    @Bean
//    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
//        RedisCacheConfiguration userCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
//                .entryTtl(Duration.ofMinutes(5)).prefixKeysWith("timeout_cache");
//        return RedisCacheManager.builder(connectionFactory).cacheDefaults(userCacheConfiguration).build();
//    }

    @Bean public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 生成一个默认配置，通过config对象即可对缓存进行自定义配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        // 设置一个初始化的缓存空间set集合
        Set<String> cacheNames =  new HashSet<>();
        cacheNames.add("timeout-cache-vipCache");
        cacheNames.add("timeout-cache-appKeyCache");
        cacheNames.add("timeout-cache-coinPriceCache");
        cacheNames.add("timeout-cache-labelCache");
        cacheNames.add("timeout-cache-giftCache");
        cacheNames.add("timeout-cache-configWxPayCache");
        cacheNames.add("timeout-cache-configWxPayByAppPackageIdAndPhoneSystemAndType");
        cacheNames.add("timeout-cache-warnManUserCache");
        cacheNames.add("timeout-cache-talkingSkillCache");
        cacheNames.add("timeout-cache-activeConfigurationCache");
        cacheNames.add("timeout-cache-textCommunicationCache");
        cacheNames.add("timeout-cache-commentNoticeCache");
        cacheNames.add("timeout-cache-newBieGuideCache");
        cacheNames.add("timeout-cache-iconOfficialCache");
        cacheNames.add("timeout-cache-prizeCache");
        cacheNames.add("timeout-cache-api-getIntegralLevelAndTitle");
        cacheNames.add("timeout-cache-activeGameRewardCache");
        cacheNames.add("timeout-cache-getCoolSummerActivitiesList");
        cacheNames.add("timeout-cache-gameListCache");
        // 对每个缓存空间应用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("timeout-cache-vipCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-appKeyCache",
                config.entryTtl(Duration.ofMinutes(5)));
        configMap.put("timeout-cache-coinPriceCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-labelCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-giftCache",
                config.entryTtl(Duration.ofMinutes(5)));
        configMap.put("timeout-cache-configWxPayCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-talkingSkillCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-activeConfigurationCache",
                config.entryTtl(Duration.ofMinutes(5)));
        configMap.put("timeout-cache-configWxPayByAppPackageIdAndPhoneSystemAndType",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-warnManUserCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-textCommunicationCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-commentNoticeCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-newBieGuideCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-iconOfficialCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-prizeCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-api-getIntegralLevelAndTitle",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-getCoolSummerActivitiesList",
                config.entryTtl(Duration.ofMinutes(15)));
        configMap.put("timeout-cache-activeGameRewardCache",
                config.entryTtl(Duration.ofMinutes(10)));
        configMap.put("timeout-cache-gameListCache",
                config.entryTtl(Duration.ofMinutes(10)));
        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
                .initialCacheNames(cacheNames)
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

    @Bean
    public SegmentedLockManager segmentedLockManager() {
        return new SegmentedLockManager(17);
    }

}
